package BlockingQueue;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyBlockingQueue<E> {
    // 设置队列长度
    private int size ;
    // 设置默认长度
    private static final int MAX_SIZE = 10;
    //LinkedList
    private LinkedList<E> queue = new LinkedList<E>();
    //使用锁
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();

    public MyBlockingQueue(int size){
        this.size = size;
    }
    public MyBlockingQueue(){
        this(MAX_SIZE);
    }

    /**
     * 如果阻塞队列内部的容器元素大于或者等于maxSize,此时等待消费者将元素
     * 取出
     * @param e 放入阻塞队列中的元素
     */

    public  boolean offer(E e) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() >= size) {
                condition1.await();
                return false;
            }
            queue.addLast(e);
            // 通知消费者2进行消费
            condition2.signal();
        } finally {
            lock.unlock();
        }
        return true;
    }

    /**
     * 如果内部容器是空的,等待消费者生产元素。
     * 无论是添加还是获取元素的操作,在哪之后都需要
     * 主动调用notifyAll,让等待取消
     */
    public  E take() throws InterruptedException {
        lock.lock();
        E data;
        try {
            while (queue.isEmpty()) {
                condition2.await();
            }
            data = queue.removeFirst();
            condition1.signal();
        } finally {
            lock.unlock();
        }
        return data;
    }
}
